package com.matt.foundation.utils;

import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Lists;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * *******************************
 * Created by Ron.
 * form com.matt
 * on 2017/12/14
 * *******************************
 */
@Component
@Slf4j
public class YinShiUtil {


    public static final String GET_VCR_LIST_URL = "https://open.ys7.com/api/lapp/device/list";

    //根据VCRID取摄像头
    public static final String GET_LIST_BY_VCRID = "https://open.ys7.com/api/lapp/device/camera/list";

    //取直播地址
    public static final String GET_LIST_ADDRESS  = "https://open.ys7.com/api/lapp/live/address/get";

    //更新录像机名称
    public static final String UPDATE_DEVICE_NAME = "https://open.ys7.com/api/lapp/device/name/update";

    //更新摄像头名称
    public static final String UPDATE_CAMERA_NAME = "https://open.ys7.com/api/lapp/camera/name/update";

    //开通直播
    public static final String OPEN_LIVE = "https://open.ys7.com/api/lapp/live/video/open";

    //关闭直播
    public static final String CLOSE_LIVE = "https://open.ys7.com/api/lapp/live/video/close";

    public static final String GET_ACCESS_TOKEN_UTL = "https://open.ys7.com/api/lapp/token/get";


    //获取播放地址
    public static final String PLAY_ADDRESS_V2 = "https://open.ys7.com/api/lapp/v2/live/address/get";

    public Map getCameraPlayAddress(String accessToken, String deviceSerial, Integer channel) {
        try {
            String response = HttpClientUtil.sendPost(PLAY_ADDRESS_V2, String.format(
                    "accessToken=%s&deviceSerial=%s&protocol=%s&channelNo=%d",
                    accessToken, deviceSerial, "2" /* hls */, channel ));

            Map responseMap = HttpClientUtil.objectMapper.readValue(response, Map.class);
            if ("200".equals(responseMap.get("code").toString())) {
                Map data = (Map)responseMap.get("data");

                return data;
            }
        } catch (IOException e) {
            log.info("get getVCRList error!!! ");
        }
        return null;
    }

    public String getAccessToken(String appKey, String appSecret) {
        try {
            String response = HttpClientUtil.sendPost(GET_ACCESS_TOKEN_UTL, String.format("appKey=%s&appSecret=%s", appKey, appSecret));
            Map responseMap = HttpClientUtil.objectMapper.readValue(response, Map.class);
            if ("200".equals(responseMap.get("code").toString())) {
                return ((Map) responseMap.get("data")).get("accessToken").toString();
            }
            log.error("getAccessToken exception!!! code : [{}]", responseMap.get("code").toString());
        } catch (Exception e) {
            log.info("get getAccessToken error!!! ");
        }
        return "";
    }

    public List getVCRList(String accessToken) {
        try {
            String response = HttpClientUtil.sendPost(GET_VCR_LIST_URL, String.format("accessToken=%s&pageSize=%s", accessToken, "50"));
            Map responseMap = HttpClientUtil.objectMapper.readValue(response, Map.class);
            if ("200".equals(responseMap.get("value").toString())) {
                return ((List) responseMap.get("data"));
            }
        } catch (IOException e) {
            log.info("get getVCRList error!!! ");
        }
        return null;
    }


    /**
     * @param accessToken
     * @param deviceSerial
     * @return 根据录像机ID查询摄像头
     */
    public List getVCRListByVCRID(String accessToken,String deviceSerial) {
        try {
            String response = HttpClientUtil.sendPost(GET_LIST_BY_VCRID, String.format("accessToken=%s&deviceSerial=%s&pageSize=%s", accessToken, deviceSerial,"50"));
            Map responseMap = HttpClientUtil.objectMapper.readValue(response, Map.class);
            if ("200".equals(responseMap.get("value").toString())) {
                return ((List) responseMap.get("data"));
            }else{
                log.error("Err value is :" + responseMap.get("value").toString());
            }
        } catch (Exception e) {
            log.info("get getVCRList error!!! ");
        }
        return null;
    }

    /**
     * @param accessToken
     * @param list
     * @return 批量获取摄像头直播地址  参数规则 deviceSerial:channelNo,deviceSerial:channelNo,deviceSerial:channelNo
     */
    public List getAddressList(String accessToken, List<Map<String, String>> list) {
        List<Object> result = Lists.newArrayList();
        try {
            //一次只能获取50个摄像头地址
            if(list.size() <= 50){
                String source = this.returnSource(list);
                String response = HttpClientUtil.sendPost(GET_LIST_ADDRESS, String.format("accessToken=%s&source=%s", accessToken, source));
                Map responseMap = HttpClientUtil.objectMapper.readValue(response, Map.class);
                if ("200".equals(responseMap.get("value").toString())) {
                    result =  ((List) responseMap.get("data"));
                } else {
                    log.error("Err msg is :" + responseMap.get("msg").toString());
                }
            }else{
                //List分片处理
                int start = 0;
                int maxCount = 50;
                int count = (int) Math.floor(list.size()/50)+1;
                for (int i = count; i > 0; i--) {
                    List<Map<String, String>> maps = list.subList(start, maxCount);
                    String source = this.returnSource(maps);
                    String response = HttpClientUtil.sendPost(GET_LIST_ADDRESS, String.format("accessToken=%s&source=%s", accessToken, source));
                    Map responseMap = HttpClientUtil.objectMapper.readValue(response, Map.class);
                    result.addAll((List)responseMap.get("data"));
                    start = maxCount;
                    maxCount+=50;
                    if(maxCount > list.size()){
                        maxCount = list.size();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info("get getVCRList error!!! ");
        }
        return result;
    }

    public String returnSource(List<Map<String, String>> list){
        StringBuffer sb = new StringBuffer();
        list.stream().forEach(m -> {
            String deviceSerial = m.get("deviceSerial");
            String channelNo = m.get("channelNo");
            sb.append(deviceSerial + ":" + channelNo + ",");
        });
        if(sb.length() == 0) {
            return "";
        }
        String source = sb.toString().substring(0, sb.length() - 1);
        return source;
    }

    public boolean updateVCRName(String accessToken,String deviceSerial,String deviceName) {
        try {
            String response = HttpClientUtil.sendPost(UPDATE_DEVICE_NAME, String.format("accessToken=%s&deviceSerial=%s&deviceName=%s&pageSize=%s",new Object[]{accessToken,deviceSerial,deviceName,"50"}));
            Map responseMap = HttpClientUtil.objectMapper.readValue(response, Map.class);
            if ("200".equals(responseMap.get("value").toString())) {
                log.info("更新录像机名称成功！");
                return true;
            } else {
                log.error("Err msg is :" + responseMap.get("msg").toString());
            }
        } catch (Exception e) {
            log.info("exec update error!!! ");
        }
        return false;
    }

    public boolean updateCameraName(String accessToken,String deviceSerial,String name,Integer channelNo) {
        try {
            String response = HttpClientUtil.sendPost(UPDATE_CAMERA_NAME, String.format("accessToken=%s&deviceSerial=%s&channelNo=%s&name=%s&pageSize=%s",
                    new Object[]{accessToken,deviceSerial,channelNo,name,"50"}));
            Map responseMap = HttpClientUtil.objectMapper.readValue(response, Map.class);
            if ("200".equals(responseMap.get("value").toString())) {
                log.info("更新摄像头名称成功！");
                return true;
            } else {
                log.error("Err msg is :" + responseMap.get("msg").toString());
            }
        } catch (Exception e) {
            log.info("exec update error!!! ");
        }
        return false;
    }

    public Map openLive(String accessToken,String deviceSerial,String channelNo) {
        try {
            String source = deviceSerial + ":" + channelNo;
            String response = HttpClientUtil.sendPost(OPEN_LIVE, String.format("accessToken=%s&source=%s&pageSize=%s",
                    new Object[]{accessToken,source,"50"}));
            Map responseMap = HttpClientUtil.objectMapper.readValue(response, Map.class);
            if ("200".equals(responseMap.get("value").toString())) {
                Object data = responseMap.get("data");
                if(null != data){
                    List<Map<String,Object>> list = (List<Map<String, Object>>) data;
                    log.info(list.get(0).toString());
                    return list.get(0);
                }
            } else {
                log.error("Err msg is :" + responseMap.get("msg").toString());
            }
        } catch (Exception e) {
            log.info("exec update error!!! ");
        }
        return null;
    }

    public Map closeLive(String accessToken,String deviceSerial,String channelNo) {
        try {
            String source = deviceSerial + ":" + channelNo;
            String response = HttpClientUtil.sendPost(CLOSE_LIVE, String.format("accessToken=%s&source=%s&pageSize=%s",
                    new Object[]{accessToken,source,"50"}));
            Map responseMap = HttpClientUtil.objectMapper.readValue(response, Map.class);
            if ("200".equals(responseMap.get("value").toString())) {
                Object data = responseMap.get("data");
                if(null != data){
                    List<Map<String,Object>> list = (List<Map<String, Object>>) data;
                    log.info(list.get(0).toString());
                    return list.get(0);
                }
            } else {
                log.error("Err msg is :" + responseMap.get("msg").toString());
            }
        } catch (Exception e) {
            log.info("exec update error!!! ");
        }
        return null;
    }
}
